package org.phantom.securityframework.api.domain;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.ExecutionException;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DelegatingSubject;
import org.phantom.securityframework.api.SecurityManager;

import org.phantom.securityframework.api.crypt.Encrypt;
import org.phantom.securityframework.api.exception.NullAccountException;
import org.phantom.securityframework.api.subject.AccountToken;
import org.phantom.securityframework.api.subject.Subject;
import org.phantom.securityframework.api.util.AuthUtil;
/**
 * 帐号
 * @author david
 *
 */
public class Account implements Subject,org.phantom.securityframework.api.Account{
	
	public Account() {
	}
	
	public Account(String accountId,String password){
		this.accountId = accountId;
		this.password = password;
	}
	
	private Integer id;
	private String accountId;
	private String password;
	private Integer status;
	private String statusDesc;
	@SuppressWarnings("unused")
	private String platformId;
	private String createDate;
	private String lastModifyDate;
	private String lastLoginTime;
	private List<org.phantom.securityframework.api.AccountExt> accountExts;
	
	private List<Role> roles;
	private List<org.phantom.securityframework.api.Permission> permissions;
	private List<Group> groups;
	
	
	private org.apache.shiro.subject.Subject delegate = null;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getAccountId() {
		return accountId;
	}
	public void setAccountId(String accountId) {
		this.accountId = accountId;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Integer getStatus() {
		return status;
	}
	public void setStatus(Integer status) {
		this.status = status;
	}
	public String getStatusDesc() {
		return statusDesc;
	}
	public void setStatusDesc(String statusDesc) {
		this.statusDesc = statusDesc;
	}
	public String getPlatformId() {
		return AuthUtil.getPlatformId();
	}
	public String getCreateDate() {
		return createDate;
	}
	public void setCreateDate(String createDate) {
		this.createDate = createDate;
	}
	public String getLastModifyDate() {
		return lastModifyDate;
	}
	public void setLastModifyDate(String lastModifyDate) {
		this.lastModifyDate = lastModifyDate;
	}
	public String getLastLoginTime() {
		return lastLoginTime;
	}
	public void setLastLoginTime(String lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}
	public List<org.phantom.securityframework.api.AccountExt> getAccountExts() {
		return accountExts;
	}
	public void setAccountExts(List<org.phantom.securityframework.api.AccountExt> accountExts) {
		this.accountExts = accountExts;
	}
	public List<Role> getRoles() {
		return roles;
	}
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}
	public List<org.phantom.securityframework.api.Permission> getPermissions() {
		return permissions;
	}
	public void setPermissions(List<org.phantom.securityframework.api.Permission> permissions) {
		this.permissions = permissions;
	}
	public List<Group> getGroups() {
		return groups;
	}
	public void setGroups(List<Group> groups) {
		this.groups = groups;
	}
	
	
	@Override
	public Object getPrincipal() {
		return this.getDelegate().getPrincipal();
	}
	@Override
	public PrincipalCollection getPrincipals() {
		return this.getDelegate().getPrincipals();
	}
	@Override
	public boolean isPermitted(String permission) {
		return this.getDelegate().isPermitted(permission);
	}
	@Override
	public boolean isPermitted(org.apache.shiro.authz.Permission permission) {
		return this.getDelegate().isPermitted(permission);
	}
	@Override
	public boolean[] isPermitted(String... permissions) {
		return this.getDelegate().isPermitted(permissions);
	}
	@Override
	public boolean[] isPermitted(List<org.apache.shiro.authz.Permission> permissions) {
		return this.getDelegate().isPermitted(permissions);
	}
	@Override
	public boolean isPermittedAll(String... permissions) {
		return this.getDelegate().isPermittedAll(permissions);
	}
	@Override
	public boolean isPermittedAll(Collection<org.apache.shiro.authz.Permission> permissions) {
		return this.getDelegate().isPermittedAll(permissions);
	}
	@Override
	public void checkPermission(String permission)
			throws AuthorizationException {
		this.getDelegate().checkPermission(permission);
	}
	@Override
	public void checkPermission(org.apache.shiro.authz.Permission permission)
			throws AuthorizationException {
		this.getDelegate().checkPermission(permission);
		
	}
	@Override
	public void checkPermissions(String... permissions)
			throws AuthorizationException {
		this.getDelegate().checkPermissions(permissions);
	}
	@Override
	public void checkPermissions(Collection<org.apache.shiro.authz.Permission> permissions)
			throws AuthorizationException {
		this.getDelegate().checkPermissions(permissions);
	}
	@Override
	public boolean hasRole(String roleIdentifier) {
		return this.getDelegate().hasRole(roleIdentifier);
	}
	@Override
	public boolean[] hasRoles(List<String> roleIdentifiers) {
		return this.getDelegate().hasRoles(roleIdentifiers);
	}
	@Override
	public boolean hasAllRoles(Collection<String> roleIdentifiers) {
		return this.getDelegate().hasAllRoles(roleIdentifiers);
	}
	@Override
	public void checkRole(String roleIdentifier) throws AuthorizationException {
		this.getDelegate().checkRole(roleIdentifier);
	}
	@Override
	public void checkRoles(Collection<String> roleIdentifiers)
			throws AuthorizationException {
		this.getDelegate().checkRoles(roleIdentifiers);
	}
	@Override
	public void checkRoles(String... roleIdentifiers)
			throws AuthorizationException {
		this.getDelegate().checkRoles(roleIdentifiers);
	}
	public void setDelegate(DelegatingSubject subject){
		this.delegate = subject;
	}
	private org.apache.shiro.subject.Subject getDelegate(){
		if(this.delegate==null)
			delegate = SecurityUtils.getSubject();
		return delegate;
	}
	@Override
	public boolean isAuthenticated() {
		return this.getDelegate().isAuthenticated();
	}
	@Override
	public boolean isRemembered() {
		return this.getDelegate().isRemembered();
	}
	@Override
	public Session getSession() {
		return this.getDelegate().getSession();
	}
	@Override
	public Session getSession(boolean create) {
		return this.getDelegate().getSession(create);
	}
	@Override
	public void logout() {
		this.getDelegate().logout();
	}
	@Override
	public <V> V execute(Callable<V> callable) throws ExecutionException {
		return this.getDelegate().execute(callable);
	}
	@Override
	public void execute(Runnable runnable) {
		this.getDelegate().execute(runnable);
	}
	@Override
	public <V> Callable<V> associateWith(Callable<V> callable) {
		return this.getDelegate().associateWith(callable);
	}
	@Override
	public Runnable associateWith(Runnable runnable) {
		return this.getDelegate().associateWith(runnable);
	}
	@Override
	public void runAs(PrincipalCollection principals)
			throws NullPointerException, IllegalStateException {
		this.getDelegate().runAs(principals);
	}
	@Override
	public boolean isRunAs() {
		return this.getDelegate().isRunAs();
	}
	@Override
	public PrincipalCollection getPreviousPrincipals() {
		return this.getDelegate().getPreviousPrincipals();
	}
	@Override
	public PrincipalCollection releaseRunAs() {
		return this.getDelegate().releaseRunAs();
	}
	public void login(){
		AccountToken t = new AccountToken(accountId, password, null);
		this.login(t);
	}
	public void login(Encrypt security) {
		AccountToken t = new AccountToken(accountId, password, security);
		this.login(t);
	}
	public void login(String account,String password){
		AccountToken t = new AccountToken(account, password, null);
		this.login(t);
	}
	public void login(String account,String password,Encrypt security){
		AccountToken t = new AccountToken(account, password, security);
		this.login(t);
	}
	@Override
	public void login(AuthenticationToken token){
		this.accountId = token.getPrincipal().toString();
		this.password = token.getCredentials().toString();
		
		if(accountId==null || "".equals(accountId)){
			throw new NullAccountException("accountId can't be null!");
		}
		if(password==null || "".equals(password)){
			throw new NullAccountException("password can't be null!");
		}

		org.apache.shiro.subject.Subject delegate = this.getDelegate();
		delegate.login(token);
	}
	
	
	@Override
	public void enable() throws Exception{
		if(SecurityUtils.getSecurityManager() instanceof SecurityManager){
			if(this.getId()==0){
				throw new AccountException("id can not be null!");
			}
			SecurityManager sm = (SecurityManager) SecurityUtils.getSecurityManager();
			try {
				sm.enable(this);
			} catch (Exception e) {
				throw e;
			}
		}else{
			throw new NoSuchMethodException("No such method 'enable'.SecurityManager must be instance of org.phantom.securityframework.api.SecurityManager");
		}
	}
	@Override
	public void disable() throws Exception{
		if(SecurityUtils.getSecurityManager() instanceof SecurityManager){
			if(this.getId()==0){
				throw new AccountException("id can not be null!");
			}
			SecurityManager sm = (SecurityManager) SecurityUtils.getSecurityManager();
			try {
				sm.disable(this);
			} catch (Exception e) {
				throw e;
			}
		}else{
			throw new NoSuchMethodException("No such method 'disable'.SecurityManager must be instance of org.phantom.securityframework.api.SecurityManager");
		}
	}
	
}
